﻿using System;
using UnityEngine;
using System.Collections.Generic;

class Game
{
	static int halfScreenWidth = 240;
	playAni player;
	BoxCollider2D playerBox;
	loopback background;
	state_Play play;


	UnityEngine.SpriteRenderer cover;

	public void Init (state_Play play)
	{
		this.playerInfo.hitDanger = false;


		this.play = play;
		play.changeBGM (level);
		halfScreenWidth = 240;
		//this.playerInfo.playerSpeedMax = play.PlayerSpeedMax;
		//this.playerInfo.playerSpeedAdd = play.playerSpeedAdd;
		//this.playerInfo.playerSpeedPush = play.playerPushSpeed;

		this.background = 
			Camera.main.transform.Find ("scene/background").GetComponent<loopback> ();
		var l1 = Resources.Load<GameObject> ("levels/l1");
		//var l2 = Resources.Load<GameObject> ("levels/l1_2");
		//var l3 = Resources.Load<GameObject> ("levels/l1_3");
		this.background.srcs = new List<GameObject> { l1, l1 };
		foreach (var s in this.background.srcs) {
			var point = s.GetComponent<startpoint> ();
			if (point != null) {
				this.playerPos.x = point.startpos;
			}
		}
		this.background.Reset ();

		this.player = Camera.main.transform.Find ("scene/player").GetComponent<playAni> ();
		this.player.SetState ("player_move");
		this.playerBox = this.player.GetComponent<BoxCollider2D> ();

		this.cover = Camera.main.transform.Find ("scene/cover/coveblack").GetComponent<SpriteRenderer> ();
		this.cover.color = new Color (0, 0, 0, 1);


	}

	float winTimer;
	public void BeginWin ()
	{
		this.player.PlayOnce ("targetdown");
		this.player.SetState (null);
		gamewin = true;
		cover.color = new Color (1, 1, 1, 0);
		winTimer = 0;
	}


	public void UpdateWin ()
	{
		winTimer += Time.deltaTime;
		if (winTimer > 3.5f) {
			if (this.Next () == false) {
				UnityEngine.SceneManagement.SceneManager.LoadScene ("Level_Success");
			}
		}

		//size
		var pos = player.transform.position;
		var target = Vector2.zero;
		pos = pos * 0.9f;
		player.transform.position = pos;

		//cam
		var s =Camera.main.orthographicSize;
		s = s * 0.9f + 50 * 0.1f;
		Camera.main.orthographicSize = s;

		//cover
		float a = cover.color.a;
		a += 0.3f * Time.deltaTime;
		if (a > 1.0) {
			a = 1.0f;

					
		}
		cover.color = new Color (1, 1, 1, a);
	}

	int level = 1;

	public bool Next ()
	{
		if (level == 1) {
			halfScreenWidth = 256;
			level = 2;
			var l2 = Resources.Load<GameObject> ("levels/l2");
			//var l2 = Resources.Load<GameObject> ("levels/l1_2");
			//var l3 = Resources.Load<GameObject> ("levels/l1_3");
			this.background.srcs = new List<GameObject> { l2, l2 };
			Reset ();
			play.changeBGM (level);
			return true;
		}
//		if (level == 2) {
//			level = 3;
//			var l2 = Resources.Load<GameObject> ("levels/l2");
//			//var l2 = Resources.Load<GameObject> ("levels/l1_2");
//			//var l3 = Resources.Load<GameObject> ("levels/l1_3");
//			this.background.srcs = new List<GameObject> { l2, l2 };
//			Reset ();
//			play.changeBGM (level);
//			return true;
//		}
//		if (level == 3) {
//			level = 4;
//			var l2 = Resources.Load<GameObject> ("levels/l2");
//			//var l2 = Resources.Load<GameObject> ("levels/l1_2");
//			//var l3 = Resources.Load<GameObject> ("levels/l1_3");
//			this.background.srcs = new List<GameObject> { l2, l2 };
//			Reset ();
//			play.changeBGM (level);
//			return true;
//		}
		return false;
	}

	void Reset ()
	{
		Camera.main.orthographicSize = 135.0f;
		this.background.Reset ();
		camPos = Vector2.zero;
		playerPos = Vector2.zero;
		foreach (var s in this.background.srcs) {
			var point = s.GetComponent<startpoint> ();
			if (point != null) {
				this.playerPos.x = point.startpos;
			}
		}
		this.player.PlayOnce ("player_move");
		this.player.SetState ("player_move");

		gameover = false;
		gamewin = false;
		playerInfo = new PlayerInfo ();
	}

	Vector2 camPos = Vector2.zero;
	Vector2 playerPos = Vector2.zero;

	public void Update ()
	{
		if (this.gamewin) {
			{
				UpdateWin ();

			}
		} else {
			if (this.gameover == false) {
				float a = cover.color.a;
				float r= cover.color.r;
				float g= cover.color.g;
				float b= cover.color.b;
				a -= 2.0f * Time.deltaTime;
				if (a < 0) {
					a = 0;
				}
				cover.color = new Color (r, g, b, a);
			} else {
				float a = cover.color.a;
				a += 1.0f * Time.deltaTime;
				if (a > 1.0) {
					a = 1.0f;
					this.Reset ();
				}
				cover.color = new Color (0, 0, 0, a);
			}

			//角色控制
			playerControl ();

			//摄像机跟踪角色
			cameraFollow ();

			//更新位置
			this.updatepos ();
		}


	}

	public bool gameover = false;
	public bool gamewin = false;
	bool lastHitWallUp = false;
	int hitWallCount = 0;
	//角色控制
	void playerControl ()
	{
		if (gameover || gamewin)
			return;
		
		if (this.playerInfo.hitDanger) {
			this.player.PlayOnce ("player_die");
			this.player.SetState (null);
			gameover = true;
			return;
		}
		if (this.playerInfo.hitWin) {
			this.BeginWin ();

			return;
		}
		this.playerControl_TestBound ();

		playerPos.y += playerInfo.playerAddY;

		if (playerInfo.hitWallUp == true) {
			
			if (Input.GetKeyDown (KeyCode.Space)) {
				playerInfo.playerSpeed = play.playerPushSpeed;
				playerInfo.pushPress = true;
				playerInfo.pushTimer = 0;
			}
		} else {

			var xdir = Input.GetAxis ("Horizontal");
			if (xdir > 0 && playerInfo.hitWallXMax == false)
				playerPos.x += xdir * play.playerHSpeed * Time.deltaTime;
			if (xdir < 0 && playerInfo.hitWallXMin == false)
				playerPos.x += xdir * play.playerHSpeed * Time.deltaTime;
		}


//		if (lastHitWallUp) {
//			if (lastHitWall != null) {
//
//				playerPos.x = (int)(lastHitWall.position.x - lastHitPos);
//			}
//
//		}

		//poslimit
		if (playerPos.x < -halfScreenWidth * 1.1f)
			playerPos.x = -halfScreenWidth * 1.1f;
		if (playerPos.x > halfScreenWidth * 1.1f)
			playerPos.x = halfScreenWidth * 1.1f;


		if (playerInfo.hitCoin != null) {
			if (playerInfo.hitCoin.price > 0) {
				playerInfo.coin += playerInfo.hitCoin.price;
				playerInfo.hitCoin.onGet ();
				//playerInfo.hitCoin.price = 0;
			}
		}
		if (playerInfo.hitWallUp) {
			if (hitWallCount < 2)
				hitWallCount++;
			if (hitWallCount > 1 && lastHitWallUp == false) {
				this.player.PlayOnce ("player_tophit");
				this.player.SetState ("player_topstay");
				lastHitWallUp = true;
				//lastHitWall = playerInfo.hitWall;

				//lastHitPos = (int)(lastHitWall.position.x - playerPos.x);
				//Debug.Log ("hit:" + lastHitPos);
			}
		} else {
			if (hitWallCount > -1)
				hitWallCount--;
			
			if (hitWallCount < 0 && lastHitWallUp == true) {
				this.player.PlayOnce ("player_backpush");
				this.player.SetState ("player_move");
				lastHitWallUp = false;
				//lastHitWall = null;
				//Debug.Log ("unhit");
			}
		}



	}

	public class PlayerInfo
	{
		public bool hitDanger = false;
		public bool hitWin = false;
		public coin hitCoin;
		public int coin = 0;
		public Transform hitWall;
		public bool hitWallUp;
		public bool hitWallDown;
		public bool hitWallXMin;
		public bool hitWallXMax;
		public float playerSpeed;
		public float pushTimer = 0;
		public bool pushPress = false;
		//		public  float playerSpeedMax = 150;
		//		public  float playerSpeedAdd = 30;
		//		public float playerSpeedPush =-75;
		public float playerAddY = 0;
	}

	public PlayerInfo playerInfo = new PlayerInfo ();
	public Transform lastHitWall = null;
	public float lastHitPos = 0;

	void playerControl_TestBound ()
	{
		var mat = playerBox.transform.localToWorldMatrix;
		Vector2 pout = mat.MultiplyPoint (playerBox.offset);

		playerInfo.hitCoin = null;
		//撞墙判定
		playerInfo.hitWallUp = false;
		playerInfo.hitWallDown = false;
		//playerInfo.hitWall = null;
		playerInfo.playerAddY = 0;
		var addysrc = playerInfo.playerSpeed * Time.deltaTime;
		var addy = addysrc;
		if (addy >= 0) {
			if (addy < 4)
				addy = 4;
			{
				Collider2D[] res = Physics2D.OverlapBoxAll (pout + new Vector2 (0, addy), playerBox.size, 0);

				//int hit =Physics2D.OverlapCollider (playerBox, f2d, res);
				if (res.Length > 0) {
					foreach (var r in res) {
						if (r == playerBox)
							continue;//碰撞到角色了play
						if (r.GetComponent<wall> () != null) {
							playerInfo.hitWallUp = true;
							playerInfo.hitWall = r.transform;
						}
						if (r.GetComponent<danger> () != null) {
							playerInfo.hitDanger = true;
						} 
						if (r.GetComponent<coin> () != null) {
							playerInfo.hitCoin = r.GetComponent<coin> ();
						}
						if (r.GetComponent<win> () != null) {
							playerInfo.hitWin = true;
						}
					}
				}
			}
		} else if (addy <= 0) {
			if (addy > -4)
				addy = -4;
			{
				Collider2D[] res = Physics2D.OverlapBoxAll (pout + new Vector2 (0, addy), playerBox.size, 0);

				//int hit =Physics2D.OverlapCollider (playerBox, f2d, res);
				if (res.Length > 0) {
					foreach (var r in res) {
						if (r == playerBox)
							continue;//碰撞到角色了play
						if (r.GetComponent<wall> () != null) {
							playerInfo.hitWallDown = true;
						} 
						if (r.GetComponent<danger> () != null) {
							playerInfo.hitDanger = true;
						} 
						if (r.GetComponent<coin> () != null) {
							playerInfo.hitCoin = r.GetComponent<coin> ();
						}
						if (r.GetComponent<win> () != null) {
							playerInfo.hitWin = true;
						}
					}
				}
			}
		}
		if (playerInfo.hitWallUp) {
			if (playerInfo.playerSpeed > 0)
				playerInfo.playerSpeed *= 0.5f;
			playerInfo.playerAddY = 0;

		} else if (playerInfo.hitWallDown) {
			if (playerInfo.playerSpeed < 0)
				playerInfo.playerSpeed *= 0.5f;
			playerInfo.playerAddY = 0;
		} else {
			playerInfo.playerAddY = addysrc;
			if (playerInfo.playerSpeed > 0) {
				playerInfo.playerSpeed += Time.deltaTime * play.playerSpeedAdd;
			} else {
				//jump
				playerInfo.pushTimer += Time.deltaTime;
				if (this.playerInfo.pushPress && playerInfo.pushTimer < play.playerPushHoldTime && Input.GetKey (KeyCode.Space)) {
					playerInfo.playerSpeed += Time.deltaTime * play.playerSpeedAdd * play.playerPushHoldScale;
				} else {
					this.playerInfo.pushPress = false;
					playerInfo.playerSpeed += Time.deltaTime * play.playerSpeedAdd;// * 2;
				}

			}
			if (playerInfo.playerSpeed > play.playerSpeedMax)
				playerInfo.playerSpeed = play.playerSpeedMax;
			//playerInfo.playerSpeed += (PlayerInfo.playerSpeedMax - playerInfo.playerSpeed) * 0.1f;
		}
		//Debug.Log ("speed=" + playerInfo.playerSpeed);
		//侧面撞击判定
		playerInfo.hitWallXMin = false;
		playerInfo.hitWallXMax = false;
		{
			Collider2D[] res = Physics2D.OverlapBoxAll (pout + new Vector2 (-5, 0), playerBox.size, 0);
			Collider2D[] res2 = Physics2D.OverlapBoxAll (pout + new Vector2 (5, 0), playerBox.size, 0);
			if (res.Length > 0) {
				foreach (var r in res) {
					if (r == playerBox)
						continue;//碰撞到角色了
					if (r.GetComponent<wall> () != null) {
						playerInfo.hitWallXMin = true;
					}
				}
			}
			if (res2.Length > 0) {
				foreach (var r in res2) {
					if (r == playerBox)
						continue;//碰撞到角色了
					if (r.GetComponent<wall> () != null) {
						playerInfo.hitWallXMax = true;
					}
				}
			}
		}
	}
	//摄像机跟踪角色
	void cameraFollow ()
	{
		//cam follow
		var movex = playerPos.x - camPos.x;
		camPos.x += movex * 0.1f;
		var movey = playerPos.y - camPos.y;
		camPos.y += movey * 0.5f;
		if (camPos.x < -halfScreenWidth * 0.8)
			camPos.x = -halfScreenWidth * 0.8f;
		if (camPos.x > halfScreenWidth * 0.8)
			camPos.x = halfScreenWidth * 0.8f;
	}

	void updatepos ()
	{
		float offsetY = 32.0f;
		this.background.height = camPos.y + offsetY; 
		this.background.X = -camPos.x + -halfScreenWidth;

		this.player.transform.localPosition = new Vector3 (
			halfScreenWidth + (float)(playerPos.x - camPos.x),
			offsetY + (float)(playerPos.y - camPos.y), 
			-1);
	}
}


